package gat.api.config.aspect;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.bitsun.core.common.exception.AppException;
import gat.api.config.annotation.CheckPermissions;
import gat.application.backgroundUser.BackgroundUserService;
import gat.application.backgroundUser.UserRoleService;
import gat.common.util.CurrentThread;
import gat.dto.res.backgroundUser.BackgroundUserResDto;
import gat.infrastructure.persistence.dao.backgroundUser.PermissionsMapper;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Objects;

@Aspect
@Component
public class CheckPermissionsAspect {

    @Autowired
    private PermissionsMapper permissionsMapper;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private BackgroundUserService backgroundUserService;

    @Pointcut("@annotation(gat.api.config.annotation.CheckPermissions)")
    public void checkPermissions() {}

    @Before("checkPermissions()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        Long userId = CurrentThread.getCurrentUser().getId();
        BackgroundUserResDto backgroundUserResDto = backgroundUserService.selectOne(userId);
        if (ObjectUtil.equal(backgroundUserResDto.getUsername(), "admin")) {
            return ;
        }

        if(!Objects.isNull(userId)){
            //获取方法上有CheckPermissions注解的参数
            Class clazz = joinPoint.getTarget().getClass();
            String methodName = joinPoint.getSignature().getName();
            Class[] parameterTypes = ((MethodSignature)joinPoint.getSignature()).getMethod().getParameterTypes();
            Method method = clazz.getMethod(methodName, parameterTypes);
            if(method.getAnnotation(CheckPermissions.class) != null){
                CheckPermissions annotation = method.getAnnotation(CheckPermissions.class);
                String menuCode = annotation.value();
                if (StringUtils.isNotBlank(menuCode)) {
                    //通过用户ID、菜单编码查询是否有关联
                    List<Long> roleIds = userRoleService.selByUserId(userId);
                    //非空判断
                    if (CollectionUtil.isEmpty(roleIds)) {
                        throw new AppException("无访问权限");
                    }
                    int count = permissionsMapper.selectAuthByUserIdAndMenuCode(roleIds, menuCode);
                    if(count == 0){
                        throw new AppException("无访问权限");
                    }
                }
            }
        }
    }
}
